from distutils.core import setup
import subprocess
import shutil
import sys
import os
import py2exe #@UnusedImport - this import modifies the arguments for setup

class DeployThingSetup(object):

    def __init__(self):
        self.withInnoSetup = False
        if '--withInnoSetup' in sys.argv:
            self.withInnoSetup = True
            sys.argv.remove('--withInnoSetup')

    def main(self):
        self.updateSysPath()
        self.preferQuietOutput()
        self.cleanupPy2Exe()

        windowScripts = [
            os.path.join('src', 'deploy', 'DeployThing.py'),
        ]

        includeModules = [
            'sip',
            'xml.etree.ElementTree',
        ]

        ignoreModules = [
            'cElementTree',
            'elementtree.ElementTree',
            'PyQt4.elementtree.ElementTree',
            'IronPythonConsole',
            'System',
            'System.Windows.Forms.Clipboard',
            'clr',
            'modes.editingmodes',
            'startup',
        ]

        excludeDlls = [
            'OLEAUT32.DLL',
            'USER32.dll',
            'IMM32.DLL',
            'SHELL32.dll',
            'KERNEL32.dll',
            'COMDLG32.DLL',
            'WSOCK32.dll',
            'WINMM.DLL',
            'ADVAPI32.dll',
            'msvcrt.dll',
            'WS2_32.DLL',
            'WINSPOOL.DRV',
            'GDI32.dll',
            'VERSION.dll',
            'OLE32.dll',
        ]

        dataFiles = self.getDataFiles('ui', 'ui', ignore = ['.svn'])

        py2exeOptions = {
            'includes' : includeModules,
            'ignores' : ignoreModules,
            'dll_excludes' : excludeDlls,
        }

        setupArgs = {
            'windows' : windowScripts,
            'data_files' : dataFiles,
            'options' : {'py2exe' : py2exeOptions},
        }

        setup(**setupArgs)

        if self.withInnoSetup:
            subprocess.check_call(['Compil32.exe', '/cc', 'installer_script.iss'])

    def updateSysPath(self):
        '''Ensures that the source for the package is on the Python path.'''
        sys.path.append(os.path.abspath('src'))

    def preferQuietOutput(self):
        '''Request quiet output from distutils if we weren't given explicit instructions.'''
        if not any(['-v' in sys.argv,
                    '--verbose' in sys.argv,
                    '-q' in sys.argv,
                    '--quiet' in sys.argv, ]):
            sys.argv.append('-q')

    def cleanupPy2Exe(self):
        '''Ensure we always get a clean build by removing the output of py2exe.'''
        for target in ('build', 'dist'):
            if os.path.isdir(target):
                print 'Removing "%s" directory.' % target
                shutil.rmtree(target, ignore_errors = True)


    def getDataFiles(self, path, name, collected = None, ignore = None):
        if ignore is None:
            ignore = []

        if collected is None:
            collected = {}

        if name not in collected:
            collected[name] = []

        for f in os.listdir(path):
            if f in ignore:
                continue

            thisPath = os.path.join(path, f)
            thisName = os.path.join(name, f)

            if os.path.isdir(thisPath):
                self.getDataFiles(thisPath, thisName, collected = collected, ignore = ignore)

            elif os.path.isfile(thisPath):
                collected[name].append(thisPath)

            else:
                print 'Unrecognized file type for %s' % f

        return collected.items()

if __name__ == '__main__':
    deployThingSetup = DeployThingSetup()
    deployThingSetup.main()
